package org.tony.spider.core.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.tony.common.io.ResourcesHelper;
import org.tony.spider.core.entries.CmdType;
import org.tony.spider.core.entries.Command;
import org.tony.spider.core.entries.Rule;
import org.tony.spider.core.entries.Spider;

/**
 * This class is helper for parsing the spider-rule.xml file
 * @author Tony
 */
public class SpiderConfig
{
  private static final String SPIDER_RULES     = "spider/spider-rules.xml";
  private static final String CONFIG_FILE_PATH = "spider/spider-config.properties";

  private Map<String, Spider> spiders;
  private Properties          spiderConfigs;

  private static SpiderConfig instance         = null;

  public SpiderConfig()
  {
    spiders = new HashMap<String, Spider>();
    spiderConfigs = ResourcesHelper.loadProperties(CONFIG_FILE_PATH);
  }

  public void parse()
  {
    Document doc = null;
    InputStream fis = Thread.currentThread().getContextClassLoader().getResourceAsStream(SPIDER_RULES);
    if (fis != null)
    {
      try
      {
        doc = Jsoup.parse(fis, "UTF-8", "", Parser.xmlParser());
        Elements spiderEles = doc.select("spider");
        Iterator<Element> elesIter = spiderEles.iterator();
        while (elesIter.hasNext())
        {
          //parse spider element
          Element el = elesIter.next();
          Spider sp = new Spider();
          sp.setName(el.attr("name"));
          Elements ruleEls = el.select("rule");
          Iterator<Element> ruleIter = ruleEls.iterator();
          while (ruleIter.hasNext())
          {
            //parse rule element
            Element ruleEl = ruleIter.next();
            Rule rule = new Rule();
            rule.setId(ruleEl.attr("id"));
            Elements cmdEls = ruleEl.select("cmd");
            Iterator<Element> cmdIter = cmdEls.iterator();
            while (cmdIter.hasNext())
            {
              //parse command element
              Element cmdEl = cmdIter.next();
              Command cmd = new Command();
              cmd.setSquence(Integer.parseInt(cmdEl.attr("seq")));
              cmd.setType(CmdType.valueOf(cmdEl.attr("type")));
              Elements lableEl = cmdEl.select("label");
              String[] lables = new String[lableEl.size()];
              Iterator<Element> labIter = lableEl.iterator();
              int i = 0;
              while (labIter.hasNext())
              {
                lables[i++] = labIter.next().attr("name");
              }
              cmd.setLables(lables);
              rule.getCommands().add(cmd);
            }
            sp.getRules().put(rule.getId(), rule);
          }
          spiders.put(sp.getName(), sp);
        }
      }
      catch (IOException e)
      {
        //TODO parse exception
      }
      finally
      {
        try
        {
          fis.close();
        }
        catch (IOException e)
        {
          // TODO Auto-generated catch block
        }
      }
    }

  }

  public synchronized static SpiderConfig getInstance()
  {
    if (instance == null)
    {
      instance = new SpiderConfig();
      instance.parse();
    }
    return instance;
  }

  private Rule getRule(String spiderName, String ruleId)
  {
    Spider sb = instance.spiders.get(spiderName);
    if (sb != null)
    {
      return sb.getRules().get(ruleId);
    }
    return null;
  }

  public Rule getNovelRule(String ruleId)
  {
    return getRule("novel", ruleId);
  }

  public String getConfig(String key)
  {
    return spiderConfigs.getProperty(key);
  }

  public static void main(String[] args)
  {
    Iterator<Command> iter = getInstance().getNovelRule("zhulang").getCommands().iterator();
    while (iter.hasNext())
    {
      System.out.println(iter.next());
    }
  }
}
